package wekamushroomapplication;

import logic.Loader;
import logic.MushroomClassifier;
import logic.MushroomID3;
import logic.MushroomInfo;
import logic.MushroomNB;
import logic.MushroomkNN;
import weka.classifiers.Classifier;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.lazy.IBk;
import weka.classifiers.trees.Id3;
import weka.core.Instance;
import weka.core.Instances;

public class WekaMushroomApplication {
    
    public static void convert(String model_name) throws Exception{
        Loader.convert(model_name);
        System.out.println("ok");
    }
    public static void preprocess(String arff, int preprocess, String raw_attr) throws Exception{
        boolean[] used_attr = new boolean[MushroomInfo.NUM_ATTRIBUTES];
        for (int i=0; i<raw_attr.length(); i++){
            if (raw_attr.charAt(i) == '1'){
                used_attr[i] = true;
            } else {
                used_attr[i] = false;
            }
        }
        Instances inst = Loader.load(arff);
        if (inst == null) throw new Exception();
        inst = Loader.preProcess(inst, preprocess);
        Loader.saveInstances2arff(inst, arff);
    }
    
    public static void learn(String arg, String type) throws Exception{
        String arff = "data/"+arg+".arff";
        Instances inst = Loader.load(arff);
        Classifier classifier = null;
        int mod = 0;
        
        if (type.equals("NB")) {
            classifier = new MushroomNB();
            mod = Loader.MODEL_MUSHROOM_NB;
        } else if (type.equals("kNN")){
            classifier = new MushroomkNN(); 
            mod = Loader.MODEL_MUSHROOM_KNN;
        } else if (type.equals("ID3")) {
            classifier = new MushroomID3();
            mod = Loader.MODEL_MUSHROOM_ID3;
        } else if (type.equals("NBw")) {
            classifier = new NaiveBayes();
            mod = Loader.MODEL_WEKA_NB;
        } else if (type.equals("kNNw")) {
            classifier = new IBk();
            mod = Loader.MODEL_WEKA_KNN;
        } else if (type.equals("ID3w")) {
            classifier = new Id3();
            mod = Loader.MODEL_WEKA_ID3;
        } else {
            System.out.println("Unknown case in WekaMushroomApplication.learn()");
        }
        
        classifier.buildClassifier(inst);
        Loader.saveModel(classifier, mod, "model/"+arg+".model");
    }
    
    public static void main(String[] args) {
        try {
            if (args.length>0) {
                if (args[0].equals("convert")){
                    convert(args[1]);
                } else if (args[0].equals("preprocess")) {
                    String arff = "data/"+args[1] +".arff";
                    int preprocess = Integer.parseInt(args[2]);
                    String raw_attr= args[3];
                    preprocess(arff,preprocess,raw_attr);
                } else if (args[0].equals("learning")){
                    String type = args[2];
                    learn(args[1],type);
                } else if (args[0].equals("classify")) {
                    MushroomClassifier cls = (MushroomClassifier)Loader.loadModel(args[1]);
                    Instance in = MushroomClassifier.createInstance(args[2], cls.dataSet);
                    in.setClassValue(cls.classifyInstance(in));
                    System.out.println(MushroomInfo.singleton.ATTRIBUTE_VALUES_LONG.get(MushroomInfo.CLASS_IDX).get(in.stringValue(in.classIndex()).charAt(0)));
                } else if (args[0].equals("classifyweka")) {
                    Classifier classifier = (Classifier)Loader.loadModel(args[1]);
                    Instances inst = Loader.load("/user/data/mushroom.arff");
                    Instance in = MushroomClassifier.createInstance(args[2], inst);
                    in.setClassValue(classifier.classifyInstance(in));
                    String str = in.stringValue(in.classIndex());
                    System.out.println(MushroomInfo.singleton.ATTRIBUTE_VALUES_LONG.get(MushroomInfo.CLASS_IDX).get(str.charAt(0)));
                } else if (args[0].equals("attribute")) {
                    MushroomClassifier cls = (MushroomClassifier)Loader.loadModel(args[1]);
                    System.out.println(MushroomClassifier.getUsedAttributes(cls.dataSet));
                } else if (args[0].equals("accuracy")) {        // args[1] = algoritma, args[2] = nama file
                    Classifier classifier = Loader.loadModel(args[1]);
                    Instances inst = Loader.load(args[2]);
                    if (args[1].equals("kNN")) {
                        MushroomNB nb = new MushroomNB();
                        NaiveBayes wnb = new NaiveBayes();
                        try {
                            nb.buildClassifier(inst);
                            wnb.buildClassifier(inst);
                        } catch (Exception e) {
                            
                        }
                        System.out.println("Akurasi MushroomNB = " + nb.accuracy(inst) + "\nAkurasi WekaNB = " + MushroomClassifier.accuracy(wnb, inst));
                    } else if (args[1].equals("NB")) {
                        MushroomkNN knn = new MushroomkNN();
                        IBk wknn = new IBk();
                        try {
                            knn.buildClassifier(inst);
                            wknn.buildClassifier(inst);
                        } catch (Exception e) {
                            
                        }
                        System.out.println("Akurasi MushroomkNN = " + knn.accuracy(inst) + "\nAkurasi WekakNN = " + MushroomClassifier.accuracy(wknn, inst));
                    } else if (args[1].equals("ID3")) {
                        MushroomID3 id3 = new MushroomID3();
                        Id3 wid3 = new Id3();
                        try {
                            id3.buildClassifier(inst);
                            wid3.buildClassifier(inst);
                        } catch (Exception e) {
                            
                        }
                        System.out.println("Akurasi MushroomID3 = " + id3.accuracy(inst) + "\nAkurasi WekaID3 = " + MushroomClassifier.accuracy(wid3, inst));
                    }
                }
            } else {
                System.out.println("Unknown case in WekaMushroomApplication.main()");
            }
        } catch (Exception ex){
            ex.printStackTrace(System.out);
            System.out.println("Exception in WekaMushroomApplication.main()");
        }
    }
}
